package cn.gdut.chengcai.base;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import cn.gdut.chengcai.entity.UploadInfoEntity;
import cn.gdut.chengcai.enums.UploadFileType;
import cn.gdut.chengcai.thread.Transcoding;

/**
 * 文件上传下载工具类 <br/>
 * 文件名组成：14位数字+2位文件类型+UUID
 */
public class UploadDownloadUtil {

	// public static LogUtil log =
	// LogUtil.getInstance(UploadDownloadUtil.class.getName());

	public static void downloadAction(String fileName, HttpServletRequest request, HttpServletResponse response) {
		response.setCharacterEncoding("utf-8");
		response.setContentType("multipart/form-data");
		response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
		try {
			String uploadFilePath = getUploadFilePath(fileName);
			Integer uploadFileType = getUploadFileType(fileName);
			String path = "";
			if (StringUtils.isEmpty(uploadFileType.toString()) == true) {
				path = getUploadPath(uploadFileType) + File.separator + fileName;
			} else {
				path = getUploadPath(uploadFileType, uploadFilePath) + File.separator + fileName;
			}
			File file = new File(path);
			InputStream is = new FileInputStream(file);

			OutputStream os = response.getOutputStream();
			byte[] b = new byte[2048];
			int length;
			while ((length = is.read(b)) > 0) {
				os.write(b, 0, length);
			}
			os.close();// 关闭

			is.close();
		} catch (FileNotFoundException e) {
			// log.error(e.getMessage(), e);
		} catch (IOException e) {
			// log.error(e.getMessage(), e);
		}
	}

	public static void uploadPreviewAction(String fileName, HttpServletRequest request, HttpServletResponse response) {
		try {
			if (StringUtils.isEmpty(fileName) == true) {
				return;
			}

			String uploadFilePath = getUploadFilePath(fileName);
			Integer uploadFileType = getUploadFileType(fileName);
			String path = "";
			if (null == uploadFileType) {
				path = getUploadPath(uploadFileType) + File.separator + fileName;
			} else {
				path = getUploadPath(uploadFileType, uploadFilePath) + File.separator + fileName;
			}
			File file = new File(path);
			InputStream is = new FileInputStream(file);
			BufferedImage bi = ImageIO.read(is);

			// 禁止图像缓存。
			response.setHeader("Pragma", "no-cache");
			response.setHeader("Cache-Control", "no-cache");
			response.setDateHeader("Expires", 0);
			response.setContentType("image/jpeg");
			// 将图像输出到Servlet输出流中。
			ServletOutputStream sos = response.getOutputStream();
			ImageIO.write(bi, "jpeg", sos);

			// 关闭
			sos.close();
			is.close();
		} catch (FileNotFoundException e) {
			// log.error(e.getMessage(), e);
		} catch (IOException e) {
			// log.error(e.getMessage(), e);
		}
	}

	public static void deleteAction(String fileName) {
		String uploadFilePath = getUploadFilePath(fileName);
		Integer uploadFileType = getUploadFileType(fileName);
		String path = "";
		if (StringUtils.isEmpty(uploadFileType.toString()) == true) {
			path = getUploadPath(uploadFileType) + File.separator + fileName;
		} else {
			path = getUploadPath(uploadFileType, uploadFilePath) + File.separator + fileName;
		}
		File file = new File(path);
		if (file.exists() == true) {
			file.delete();
		}
	}

	public static String getResourceUrl(String fileName) {
		String uploadFilePath = getUploadFilePath(fileName);
		Integer uploadFileType = getUploadFileType(fileName);
		String path = "";
		if (StringUtils.isEmpty(uploadFileType.toString()) == true) {
			path = getUploadPath(uploadFileType) + File.separator + fileName;
		} else {
			path = getUploadPath(uploadFileType, uploadFilePath) + File.separator + fileName;
		}
		return path;
	}

	public static Map<Integer, UploadInfoEntity> uploadAction(HttpServletRequest request, HttpSession session,
			Integer uploadFileType, Date createTime) {
		Map<Integer, UploadInfoEntity> result = new HashMap<>();
		// 文件上传
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;

		// 多文件上传
		List<MultipartFile> files = multipartRequest.getFiles("files");
		if (files != null) {
			try {
				int i = 0;
				for (MultipartFile multipartFile : files) {
					i++;
					String filename = multipartFile.getOriginalFilename();
					if (StringUtils.isEmpty(filename) == true) {
						continue;
					}
					String randomName = UUID.randomUUID().toString().replace("-", "");
					String fileSuffix = filename.substring(filename.lastIndexOf(".", filename.length()));
					SimpleDateFormat sdfFilePath = new SimpleDateFormat(
							String.format("%syyyy%sMM%sdd%sHH%smm%sss%s", File.separator, File.separator,
									File.separator, File.separator, File.separator, File.separator, File.separator));
					SimpleDateFormat sdfFileName = new SimpleDateFormat("yyyyMMddHHmmss");
					String tempPath = sdfFilePath.format(createTime);
					String fileType = String.format("%02d", uploadFileType);
					String newFileName = sdfFileName.format(createTime) + fileType + randomName + fileSuffix;
					String path = getUploadPath(uploadFileType, tempPath) + newFileName;
					File file = new File(path);

					multipartFile.transferTo(file);

					UploadInfoEntity entity = new UploadInfoEntity();
					entity.setSourceName(filename);
					entity.setFileName(newFileName);
					entity.setFileUrl(newFileName);
					entity.setFileSuffix(fileSuffix);
					result.put(i, entity);

				}
			} catch (IllegalStateException e) {
				// log.error(e.getMessage(), e);
				e.printStackTrace();
			} catch (IOException e) {
				// log.error(e.getMessage(), e);
				e.printStackTrace();
			}
		}

		return result;
	}

	public static Map<Integer, UploadInfoEntity> uploadVideoAction(HttpServletRequest request, HttpSession session,
			Integer uploadFileType, Date createTime) {
		Map<Integer, UploadInfoEntity> result = new HashMap<>();
		// 文件上传
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;

		// 多文件上传
		List<MultipartFile> files = multipartRequest.getFiles("files");
		if (files != null) {
			try {
				int i = 0;
				for (MultipartFile multipartFile : files) {
					i++;
					String filename = multipartFile.getOriginalFilename();
					if (StringUtils.isEmpty(filename) == true) {
						continue;
					}
					String randomName = UUID.randomUUID().toString().replace("-", "");
					String fileSuffix = filename.substring(filename.lastIndexOf(".", filename.length()));
					SimpleDateFormat sdfFilePath = new SimpleDateFormat(
							String.format("%syyyy%sMM%sdd%sHH%smm%sss%s", File.separator, File.separator,
									File.separator, File.separator, File.separator, File.separator, File.separator));
					SimpleDateFormat sdfFileName = new SimpleDateFormat("yyyyMMddHHmmss");
					String tempPath = sdfFilePath.format(createTime);
					String fileType = String.format("%02d", uploadFileType);
					String newFileName = sdfFileName.format(createTime) + fileType + randomName + fileSuffix;
					String path = getUploadPath(uploadFileType, tempPath) + newFileName;
					File file = new File(path);

					multipartFile.transferTo(file);

					UploadInfoEntity entity = new UploadInfoEntity();
					entity.setSourceName(filename);
					entity.setFileName(newFileName);
					entity.setFileUrl(newFileName);
					entity.setFileSuffix(fileSuffix);
					result.put(i, entity);

					/*Transcoding transcoding = new Transcoding();
					transcoding.setSrcFilePath(path);
					new Thread(transcoding).start();*/

				}
			} catch (IllegalStateException e) {
				// log.error(e.getMessage(), e);
				e.printStackTrace();
			} catch (IOException e) {
				// log.error(e.getMessage(), e);
				e.printStackTrace();
			}
		}

		return result;
	}

	private static String getUploadPath(Integer uploadFileType) {
		return getUploadPath(uploadFileType, "");
	}

	private static String getUploadPath(Integer uploadFileType, String tempPath) {
		String path = "";
		if (isLinuxOs() == true) {
			path = "/opt/camp-uploads";// /opt目录
		} else {
			path = "d:/camp-uploads";// D盘目录
		}
		if (null == uploadFileType) {
			path += getBaseUploadURI(null) + tempPath;
		} else {
			path += getBaseUploadURI(uploadFileType) + tempPath;
		}
		File file = new File(path);
		if (file.exists() == false) {
			file.mkdirs();
		}
		return path;
	}

	private static boolean isLinuxOs() {
		if (System.getProperty("os.name").equals("Linux")) {
			return true;
		} else {
			return false;
		}
	}

	private static String getBaseUploadURI(Integer type) {
		String result = "unknowned";
		if (type != null) {
			if (type == UploadFileType.DOWNLOAD_AREA.getValue()) {
				result = "download-area";
			} else if (type == UploadFileType.PROFILE.getValue()) {
				result = "profile";
			} else if (type == UploadFileType.VOUCHER.getValue()) {
				result = "voucher";
			} else if (type == UploadFileType.IMG.getValue()) {
				result = "img";
			} else if (type == UploadFileType.SYSTEM_FILE.getValue()) {
				result = "system";
			} else if (type == UploadFileType.COURSEWARE.getValue()) {
				result = "courseware";
			} else if (type == UploadFileType.APPLY.getValue()) {
				result = "apply";
			}

		}

		result = File.separator + result;
		return result;
	}

	public static String getUploadFilePath(String fileName) {
		StringBuffer sb = new StringBuffer();
		sb.append(File.separator);
		sb.append(fileName.substring(0, 4));
		sb.append(File.separator);
		sb.append(fileName.substring(4, 6));
		sb.append(File.separator);
		sb.append(fileName.substring(6, 8));
		sb.append(File.separator);
		sb.append(fileName.substring(8, 10));
		sb.append(File.separator);
		sb.append(fileName.substring(10, 12));
		sb.append(File.separator);
		sb.append(fileName.substring(12, 14));
		return sb.toString();
	}

	public static Integer getUploadFileType(String fileName) {
		if (fileName == null || fileName.length() < 16) {
			return null;
		}

		StringBuffer sb = new StringBuffer();
		sb.append(fileName.substring(14, 16));
		String result = sb.toString();
		if (result == null) {
			return null;
		} else {
			return Integer.valueOf(result);
		}
	}
}
